package com.anji.plus.gaea.oss.ossbuilder;

import com.anji.plus.gaea.oss.config.OSSProperties;
import com.anji.plus.gaea.oss.exceptions.GaeaOSSException;
import com.anji.plus.gaea.oss.exceptions.GaeaOSSTypeLimitedExceptionBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
 * GaeaOSS标准调用接口
 * @Author: lide
 * @since 2022/3/22 14:16
 */
public interface GaeaOSSTemplate {

    final static Logger logger = LoggerFactory.getLogger(GaeaOSSTemplate.class);

    default void init(OSSProperties config){

    }
    default void close(){

    }

    /**文件后缀白名单
     * @return
     */
    String getFileTypeWhiteList();

    /**
     * 将字符串切割成list，支持|或者,分割线
     * @param listStr
     * @return
     */
    default List<String> splitToList(String listStr){
        List<String> list = new ArrayList<>();
        if(StringUtils.isEmpty(listStr)){
            return list;
        }
        if(listStr.contains("|")){
            list = Arrays.asList(listStr.split("\\|"));
        }
        if(listStr.contains(",")){
            list = Arrays.asList(listStr.split(","));
        }
        List<String> upperList = new ArrayList<>();
        upperList.addAll(list.stream().map(String::toUpperCase).collect(Collectors.toList()));
        return upperList;
    }

    /**
     * 获取上传文件的文件后缀
     * @param file
     * @return .png
     */
    default String getSuffixName(MultipartFile file){
        String originalFilename = file.getOriginalFilename();
        if(StringUtils.isEmpty(originalFilename) || !originalFilename.contains(".")){
            throw new GaeaOSSException("original file name or type is empty");
        }
        //文件后缀名
        String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
        return suffixName;
    }

    /**
     * 判断文件的后缀名是否在白名单中，存在返回true
     * @param file
     * @return
     */
    default boolean isAllowedFileSuffixName(MultipartFile file){
        String sufixwhiteListStr = getFileTypeWhiteList();
        if(sufixwhiteListStr == null){
            return true;
        }
        sufixwhiteListStr = sufixwhiteListStr.trim();
        if(StringUtils.isEmpty(sufixwhiteListStr)){
            return true;
        }
        String suffixName = getSuffixName(file).toUpperCase();
        // 文件后缀白名单校验(不区分大小写)
        List<String> sufixwhiteList = splitToList(sufixwhiteListStr);
        return sufixwhiteList.contains(suffixName);
    }

    /**
     * 判断文件后缀名是否在白名单中，如果不在报异常，中止文件保存
     * @param file
     */
    default void checkFileSuffixName(MultipartFile file){
        // 是否是允许的文件后缀
        boolean allowedFileSuffix = isAllowedFileSuffixName(file);
        if(allowedFileSuffix == false){
            logger.warn("file {} type is not in allow list {}", file.getOriginalFilename(), getFileTypeWhiteList());
            throw GaeaOSSTypeLimitedExceptionBuilder.build("file type is not in allow list");
        }
    }

    /**
     * 输入参数为前端文件上传对象MultipartFile
     * 返回的是新文件名，下载删除需要
     * @param file
     * @return 文件名，1c6bf10daa0e43ac8da32c96fc30dae7.png
     */
    default String uploadFileByInputStream(MultipartFile file) throws GaeaOSSException{
        checkFileSuffixName(file);//判断文件后缀名是否在白名单中，如果不在报异常，中止文件保存

        String suffixName = getSuffixName(file);
        String fileId = UUID.randomUUID().toString();
        fileId = fileId.replaceAll("-","");
        String fileObjectName = fileId + suffixName;
        return uploadFileByInputStream(file, fileObjectName);
    }

    /**
     * 输入参数为前端文件上传对象MultipartFile
     * 返回的是objectName 作为下载文件的依据，客服端需要存储
     *
     * @param file
     * @param fileObjectName 上传原始文件名 OrderExcel20220322.xls
     * @return 上传原始文件名 OrderExcel20220322.xls
     */
    String uploadFileByInputStream(MultipartFile file, String fileObjectName) throws GaeaOSSException;

    /**
     * 根据fileObjectName下载文件流
     *
     * @param fileObjectName 402b6193-e70e-40a9-bf5b-73a78ea1e8ab.png
     * @return
     */
    byte[] downloadFile(String fileObjectName) throws GaeaOSSException;

    /**
     * 根据fileObjectName删除
     *
     * @param fileObjectName 402b6193-e70e-40a9-bf5b-73a78ea1e8ab.png
     * @return
     */
    void deleteFile(String fileObjectName);
    void deleteFiles(List<String> fileObjectNames);
}
